home *** CD-ROM | disk | FTP | other *** search
- #include "MyHeader.h"
-
-
-
-
- MyShape * MyShapeNew(void)
- {
- return calloc(sizeof (MyShape), 1);
- }
-
- void MyShapeDispose(MyShape * shape)
- {
- if(shape){
- free(shape->pointList);
- free(shape->triangleList);
- }
- free(shape);
- }
-
- MyShape * MyShapeLoad(char * fileName)
- {
- FILE * f;
- MyShape * shape = NULL;
-
- char s[1000];
- long x;
- MyVector * p;
- MyTri * t;
- float len;
-
- /********/
-
- f = fopen(fileName, "r");
- if(!f) goto fail1;
-
- shape = MyShapeNew();
-
- fgets(s, sizeof s, f);
- sscanf(s, "%ld", &shape->pointCount);
- shape->pointList = malloc(sizeof (MyVector) * shape->pointCount);
- for(x = 0; x < shape->pointCount; x++){
- p = &shape->pointList[x];
- fgets(s, sizeof s, f);
- sscanf(s, "%f,%f,%f", &p->x, &p->y, &p->z);
-
- len = MyVectorLength(p);
- if(len > shape->maxDimention) shape->maxDimention = len;
- }
-
- fgets(s, sizeof s, f);
- sscanf(s, "%ld", &shape->triangleCount);
- shape->triangleList = malloc(sizeof (MyTri) * shape->triangleCount);
- for(x = 0; x < shape->triangleCount; x++){
- t = &shape->triangleList[x];
- fgets(s, sizeof s, f);
- sscanf(s, "%ld,%f,%f,%ld,%f,%f,%ld,%f,%f,%hd",
- &t->corner[0].pointNumber, &t->corner[0].u, &t->corner[0].v,
- &t->corner[1].pointNumber, &t->corner[1].u, &t->corner[1].v,
- &t->corner[2].pointNumber, &t->corner[2].u, &t->corner[2].v,
- &t->texture);
- }
-
-
- fclose(f);
- fail1:
- return shape;
- }
-
- #define margin 0.001
-
- static long AddToNormalList(long * countVar, MyVector * normalList, MyVector * newNormal)
- {
- long x;
-
- for(x = 0; x < *countVar; x++){
- if(MyVectorDistance(newNormal, &normalList[x]) < margin) return x;
- }
-
- x = *countVar;
-
- normalList[x] = *newNormal;
-
- (*countVar)++;
-
- return x;
- }
-
- static void CalcTriNormal(const MyShape * shape, long theTri, MyVector * normal)
- {
- MyTri * tri;
- MyVector * points;
- MyVector v1, v2;
- /********/
-
- points = shape->pointList;
- tri = &shape->triangleList[theTri];
- MyVectorSubtract(&points[tri->corner[1].pointNumber], &points[tri->corner[0].pointNumber], &v1);
- MyVectorSubtract(&points[tri->corner[2].pointNumber], &points[tri->corner[0].pointNumber], &v2);
- MyVectorCrossProduct(&v2, &v1, normal);
- MyVectorNormalize(normal, normal);
-
- }
-
- void MyShapeCalculateNormals(MyShape * shape, short mode)
- {
- long x, y, c, pn;
- MyVector * points;
- long * normalTable; // the number of entries is triangleCount for flat shading or triangleCount * 3 for per vertex shading
- long normalCount;
- long normalCount2;
- MyVector * normalList;
- MyVector * normalList2;
- MyVector n, n2, n3;
- MyTri * tri;
- float vectorDistance;
-
- /*****/
-
-
-
- points = shape->pointList;
- normalCount = 0;
-
- switch(mode){
- case 0:
- // per vertex - only for spheres
- MYCALLOC(normalTable, shape->triangleCount * 3);
- MYCALLOC(normalList, shape->triangleCount * 3);
-
- for(x = 0; x < shape->triangleCount; x++){
- tri = &shape->triangleList[x];
- for(c = 0; c < 3; c++){
- MyVectorNormalize(&points[tri->corner[c].pointNumber], &n);
- normalTable[x * 3 + c] = AddToNormalList(&normalCount, normalList, &n);
- }
- }
- break;
- case 1:
- // flat shading
- MYCALLOC(normalTable, shape->triangleCount);
- MYCALLOC(normalList, shape->triangleCount);
-
- for(x = 0; x < shape->triangleCount; x++){
- CalcTriNormal(shape, x, &n);
- normalTable[x] = AddToNormalList(&normalCount, normalList, &n);
- }
- break;
- case 2:
- // per vertex - auto smooth
- MYCALLOC(normalTable, shape->triangleCount * 3);
- MYCALLOC(normalList, shape->triangleCount * 3);
- MYCALLOC(normalList2, shape->triangleCount);
- for(x = 0; x < shape->triangleCount; x++){
- CalcTriNormal(shape, x, &n);
- tri = &shape->triangleList[x];
-
- for(c = 0; c < 3; c++){
- normalList2[0] = n;
- normalCount2 = 1;
- pn = tri->corner[c].pointNumber;
-
- for(y = 0; y < shape->triangleCount; y++){
- if(shape->triangleList[y].corner[0].pointNumber == pn ||
- shape->triangleList[y].corner[1].pointNumber == pn ||
- shape->triangleList[y].corner[2].pointNumber == pn){
-
- CalcTriNormal(shape, y, &n2);
- vectorDistance = MyVectorDistance(&n, &n2);
- if(vectorDistance < 1.0){
- AddToNormalList(&normalCount2, normalList2, &n2);
- }
-
- }
- }
- n3.x = n3.y = n3.z = 0;
- for(y = 0; y < normalCount2; y++){
- MyVectorAdd(&normalList2[y], &n3, &n3);
- }
- MyVectorNormalize(&n3, &n3);
- normalTable[x * 3 + c] = AddToNormalList(&normalCount, normalList, &n3);
- }
- }
- mode = 0; // for setting shape->normalMode
- MYFREE(normalList2);
- break;
- }
- MYREALLOC(normalList, normalCount);
-
- shape->normalTable = normalTable;
- shape->normalList = normalList;
- shape->normalCount = normalCount;
- shape->normalMode = mode;
- }
-
-
-
-
-
-
- void MyShapeSave(MyShape * shape, char * fileName)
- {
- long x;
- MyVector * p;
- MyTri * t;
- FILE * f;
-
- f = fopen(fileName, "w");
- fprintf(f, "%ld\n", shape->pointCount);
-
- for(x = 0; x < shape->pointCount; x++){
- p = &shape->pointList[x];
- fprintf(f, "%f,%f,%f\n", p->x, p->y, p->z);
- }
-
- fprintf(f, "%ld\n", shape->triangleCount);
-
- for(x = 0; x < shape->triangleCount; x++){
- t = &shape->triangleList[x];
- fprintf(f, "%ld,%f,%f,%ld,%f,%f,%ld,%f,%f,%hd\n",
- t->corner[0].pointNumber, t->corner[0].u, t->corner[0].v,
- t->corner[1].pointNumber, t->corner[1].u, t->corner[1].v,
- t->corner[2].pointNumber, t->corner[2].u, t->corner[2].v,
- t->texture);
- }
-
-
- fclose(f);
-
-
- }
-